package site.teamo.biu.net.server.service.impl;

import cn.hutool.cache.Cache;
import cn.hutool.cache.CacheUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import site.teamo.biu.net.common.constant.YesOrNo;
import site.teamo.biu.net.common.exception.BiuNetBusinessException;
import site.teamo.biu.net.common.web.constant.ResponseCode;
import site.teamo.biu.net.common.web.mapper.SystemConfigMapper;
import site.teamo.biu.net.server.entity.ClientDO;
import site.teamo.biu.net.server.mapper.ClientMapper;
import site.teamo.biu.net.server.pojo.dto.ClientDTO;
import site.teamo.biu.net.server.service.ClientManagementService;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author haocongshun
 * @date 2023/03/06 15:27:08
 */
@Service
public class ClientManagementServiceImpl extends ServiceImpl<ClientMapper, ClientDO> implements ClientManagementService {

    private Cache<String, YesOrNo> onlineStatus = CacheUtil.newTimedCache(90000L);


    @Resource
    private SystemConfigMapper systemConfigMapper;

    @Override
    public List<ClientDTO> queryClientList() {
        List<ClientDO> clientDOList = this.baseMapper.selectList(new QueryWrapper<ClientDO>().orderByDesc("create_time"));
        return clientDOList.stream()
                .map(clientDO -> ClientDTO.from(clientDO, this.isOnline(clientDO.getToken()).booleanValue))
                .collect(Collectors.toList());
    }

    @Override
    public ClientDTO queryClientByToken(String token) {
        ClientDO clientDO = this.baseMapper.selectOne(new QueryWrapper<ClientDO>().eq("token", token));
        if (clientDO == null) {
            return null;
        }
        return ClientDTO.from(clientDO, this.isOnline(clientDO.getToken()).booleanValue);
    }

    @Override
    public String createClient(String clientId, String name) {
        if (this.baseMapper.selectById(clientId) != null) {
            throw new BiuNetBusinessException(ResponseCode.BUSINESS_ERROR, "客户端[client => " + clientId + "]已经存在");
        }
        ClientDO clientDO = new ClientDO()
                .setId(clientId)
                .setName(name)
                .setToken(IdUtil.randomUUID());
        this.baseMapper.insert(clientDO);
        return clientDO.getToken();
    }

    @Override
    public String regenerateToken(String clientId) {
        String token = IdUtil.randomUUID();
        this.baseMapper.updateById(new ClientDO()
                .setId(clientId)
                .setToken(token));
        return token;
    }

    @Override
    public Boolean deleteClient(String clientId) {
        this.baseMapper.deleteById(clientId);
        return true;
    }

    @Override
    public void onHeartbeat(String token) {
        onlineStatus.put(token, YesOrNo.YES);
    }

    @Override
    public YesOrNo isExist(String token) {
        boolean flag = onlineStatus.containsKey(token);
        if (flag) {
            return YesOrNo.YES;
        }
        ClientDTO clientDTO = this.queryClientByToken(token);
        if (clientDTO != null) {
            onlineStatus.put(token, YesOrNo.NO);
            return YesOrNo.YES;
        }
        return YesOrNo.NO;
    }

    @Override
    public YesOrNo isOnline(String token) {
        YesOrNo online = onlineStatus.get(token);
        if (online == null) {
            return YesOrNo.NO;
        }
        return online;
    }
}
